package com.mobile.mobilehardware.camera;

import ohos.app.Context;
import ohos.media.camera.CameraKit;
import ohos.media.camera.params.Metadata;
import ohos.media.camera.params.ParameterKey;
import ohos.media.camera.params.PropertyKey;
import ohos.media.image.common.ImageFormat;
import ohos.utils.Scope;
import ohos.utils.zson.ZSONArray;
import ohos.utils.zson.ZSONObject;

import java.util.List;


/**
 * @author guxiaonian
 */
class CameraInfo {

    private static final String UNKNOWN = "UNKNOWN";

    private static final String TAG = CameraInfo.class.getSimpleName();

    static ZSONObject cameraInfo(Context context) {
        CameraBean cameraBean = new CameraBean();
        ZSONArray jsonArray = new ZSONArray();
        CameraKit cameraKit = CameraKit.getInstance(context);

        for (String cameraId : cameraKit.getCameraIds()) {
            CameraBean.CameraInfoBean cameraInfoBean = new CameraBean.CameraInfoBean();
            ohos.media.camera.device.CameraInfo camerainfo= cameraKit.getCameraInfo(cameraId);
            ohos.media.camera.device.CameraAbility cameraability= cameraKit.getCameraAbility(cameraId);
            //摄像头位置 后置 前置 外置
            cameraInfoBean.setCameraFacing(getFacing(camerainfo.getFacingType()));

            List<Integer> ints = cameraability.getSupportedFormats();
            if (ints.size() > 0) {
                ZSONArray jsonArrayOutputFormats = new ZSONArray();
                for (int i : ints) {
                    jsonArrayOutputFormats.add(getFormat(i));
                }
                cameraInfoBean.setOutputFormats(jsonArrayOutputFormats);
            }

            //TODO 本相机设备支持的自动曝光模式列表
            int[] aeAvailableModes = cameraability.getSupportedFlashMode();
            if (aeAvailableModes.length > 0) {
                ZSONArray jsonArrayAeAvailableModes = new ZSONArray();
                for (int i : aeAvailableModes) {
                    jsonArrayAeAvailableModes.add(getAeAvailableModes(i));
                }
                cameraInfoBean.setAeAvailableModes(jsonArrayAeAvailableModes);
            }

            //TODO 相机设备支持的自动对焦（AF）模式列表
            int[] afAvailableModes = cameraability.getSupportedAfMode();
            if (afAvailableModes.length != 0) {
                ZSONArray jsonArrayAfAvailableModes = new ZSONArray();
                for (int i : afAvailableModes) {
                    jsonArrayAfAvailableModes.add(getAfAvailableModes(i));
                }
                cameraInfoBean.setAfAvailableModes(jsonArrayAfAvailableModes);
            }

            //TODO 本相机设备支持的视频稳定模式列表
            List<PropertyKey.Key<?>> supportedProperties = cameraability.getSupportedProperties();
            if (supportedProperties.contains(PropertyKey.VIDEO_STABILIZATION_SUPPORT)) {
                Boolean videoStabilizationModes = cameraability.getPropertyValue(PropertyKey.VIDEO_STABILIZATION_SUPPORT);
                ZSONArray jsonArrayVideoStabilizationModes = new ZSONArray();
                jsonArrayVideoStabilizationModes.add(getVideoStabilizationModes(videoStabilizationModes));
                cameraInfoBean.setVideoStabilizationModes(jsonArrayVideoStabilizationModes);
            }

            //TODO 本相机设备支持的自动白平衡模式列表
            int[] awbAvailableModes = cameraability.getSupportedAwbMode();
            if (awbAvailableModes.length != 0) {
                ZSONArray jsonArrayAwbAvailableModes = new ZSONArray();
                for (int i : awbAvailableModes) {
                    jsonArrayAwbAvailableModes.add(getAwbAvailableModes(i));
                }
                cameraInfoBean.setAwbAvailableModes(jsonArrayAwbAvailableModes);
            }

            //TODO 相机设备支持的帧频范围列表
            List<ParameterKey.Key<?>> supportedParameters = cameraability.getSupportedParameters();
            if (supportedParameters.contains(ParameterKey.EXPOSURE_FPS_RANGE)) {
                List<Scope<Integer>> fpsRanges = cameraability.getParameterRange(ParameterKey.EXPOSURE_FPS_RANGE);
                if (fpsRanges != null && fpsRanges.size() > 0) {
                    ZSONArray jsonArrayFpsRanges = new ZSONArray();
                    for (Scope<Integer> i : fpsRanges) {
                        jsonArrayFpsRanges.add(i);
                    }
                    cameraInfoBean.setFpsRanges(jsonArrayFpsRanges);
                }
            }

            //摄像头是否支持闪光灯
            if (aeAvailableModes.length > 0) {
                Boolean flashInfoAvailable = true;
                if (flashInfoAvailable != null) {
                    cameraInfoBean.setCameraFlashInfo(flashInfoAvailable);
                }
            }

             //TODO 定义结果将由多少个子组件组成
            if (supportedProperties.contains(PropertyKey.PARTIAL_RESULT_COUNT)) {
                int requestPartialResultCount = cameraability.getPropertyValue(PropertyKey.PARTIAL_RESULT_COUNT);
                if (requestPartialResultCount > 0) {
                    cameraInfoBean.setRequestPartialResultCount(requestPartialResultCount);
                }
            }


            //TODO 活动区域宽度和作物区域宽度以及活动区域高度和作物区域高度之间的最大比率
            float[] scalerAvailableMaxDigitalZoom = cameraability.getSupportedZoom();
            if (!((int)scalerAvailableMaxDigitalZoom[1] == 1 && ((int)scalerAvailableMaxDigitalZoom[0] == (int)scalerAvailableMaxDigitalZoom[1]))) {
                cameraInfoBean.setScalerAvailableMaxDigitalZoom(scalerAvailableMaxDigitalZoom[1]);
            }

            //TODO 需要以顺时针方向旋转输出图像以使其在设备屏幕上以其原始方向直立
            if (supportedProperties.contains(PropertyKey.SENSOR_ORIENTATION)) {
                int sensorOrientation = cameraability.getPropertyValue(PropertyKey.SENSOR_ORIENTATION);
                if (sensorOrientation > 0) {
                    cameraInfoBean.setSensorOrientation(sensorOrientation);
                }
            }

            //TODO 本相机设备支持的脸部识别模式列表
            int[] availableFaceDetectModes = cameraability.getSupportedFaceDetection();
            if (availableFaceDetectModes.length > 0) {
                ZSONArray jsonArrayAvailableFaceDetectModes = new ZSONArray();
                for (int i : availableFaceDetectModes) {
                    jsonArrayAvailableFaceDetectModes.add(getAvailableFaceDetectModes(i));
                }
                cameraInfoBean.setAvailableFaceDetectModes(jsonArrayAvailableFaceDetectModes);
            }

            jsonArray.add(cameraInfoBean.toJSONObject());
        }

        cameraBean.setCameraInfo(jsonArray);
        return cameraBean.toJSONObject();
    }

    private static String getAvailableFaceDetectModes(int availableFaceDetectModes) {
        switch (availableFaceDetectModes) {
            case Metadata.FaceDetectionType.FACE_DETECTION:
                return "ON";
            case Metadata.FaceDetectionType.FACE_DETECTION_OFF:
                return "OFF";
            case Metadata.FaceDetectionType.FACE_SMILE_DETECTION:
                return "SMILE";
            default:
                return UNKNOWN + "-" + availableFaceDetectModes;

        }
    }

    private static String getAwbAvailableModes(int awbAvailableModes) {
        switch (awbAvailableModes) {
            case Metadata.AwbMode.AWB_INACTIVE:
                return "OFF";
            case Metadata.AwbMode.AWB_AUTOMATIC:
                return "AUTO";
            default:
                return UNKNOWN + "-" + awbAvailableModes;

        }
    }


    private static String getVideoStabilizationModes(boolean videoStabilizationModes) {
        if (videoStabilizationModes)
            return "ON";
        return "OFF";
    }

    private static String getAfAvailableModes(int afAvailableModes) {
        switch (afAvailableModes) {
            case Metadata.AfMode.AF_MODE_OFF:
                return "OFF";
            case Metadata.AfMode.AF_MODE_CONTINUOUS:
                return "CONTINUOUS";
            case Metadata.AfMode.AF_MODE_TOUCH_LOCK:
                return "TOUCH LOCKED";
            default:
                return UNKNOWN + "-" + afAvailableModes;
        }
    }

    private static String getAeAvailableModes(int aeAvailableModes) {
        switch (aeAvailableModes) {
            case Metadata.FlashMode.FLASH_ALWAYS_OPEN:
                return "ON_ALWAYS_FLASH";
            case Metadata.FlashMode.FLASH_AUTO:
                return "ON_AUTO_FLASH";
            case Metadata.FlashMode.FLASH_CLOSE:
                return "OFF";
            case Metadata.FlashMode.FLASH_OPEN:
                return "ON";
            default:
                return UNKNOWN + "-" + aeAvailableModes;

        }
    }

    private static String getFacing(Integer facing) {
        if (facing == null) {
            return UNKNOWN;
        }
        switch (facing) {
            case ohos.media.camera.device.CameraInfo.FacingType.CAMERA_FACING_FRONT:
                return "FRONT";
            case ohos.media.camera.device.CameraInfo.FacingType.CAMERA_FACING_BACK:
                return "BACK";
            case ohos.media.camera.device.CameraInfo.FacingType.CAMERA_FACING_OTHERS:
                return "OTHERS";
            default:
                return UNKNOWN + "-" + facing;
        }
    }

    private static String getFormat(int format) {
        switch (format) {
            case ImageFormat.JPEG:
                return "JPEG";
            case ImageFormat.NV21:
                return "NV21";
            case ImageFormat.RAW10:
                return "RAW10";
            case ImageFormat.RAW16:
                return "RAW16";
            case ImageFormat.YUV420_888:
                return "YUV420_888";
            case ImageFormat.H264:
                return "H264";
            case ImageFormat.H265:
                return "H265";
            default:
                return UNKNOWN + "-" + format;
        }
    }
}
